package cn.com.easy.pay.alipay.union.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.com.easy.exception.BusinessException;
import cn.com.easy.pay.alipay.union.config.AlipayUnionConfig;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;

/**
 * 支付宝app退款接口，<br/>
 * 详参：https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7395905
 * .0.0.0ej0mo&docType=4&apiId=759
 * 
 * @author nibili 2017年4月7日
 * 
 */
public abstract class AlipayTradeRefundBaseController {

	private Logger logger = LoggerFactory.getLogger(AlipayTradeRefundBaseController.class);

	/**
	 * 阿里配置参数
	 * 
	 * @return
	 * @author nibili 2017年4月1日
	 */
	public abstract AlipayUnionConfig getAlipayConfig(HttpServletRequest httpServletRequest) throws BusinessException;

	/**
	 * 退款参数
	 * 
	 * @param httpServletRequest
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年4月7日
	 */
	public abstract AlipayTradeRefundModel getAlipayTradeRefundModel(HttpServletRequest httpServletRequest) throws BusinessException;

	/**
	 * 退款成功<br/>
	 * 返回的对实会被序列化，传递到客户端
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param notifyParam
	 * @throws BusinessException
	 * @author nibili 2017年4月7日
	 */
	public abstract Object successCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AlipayTradeRefundResponse response)
			throws BusinessException;

	/**
	 * 退款失败<br/>
	 * 返回的对实会被序列化，传递到客户端
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param response
	 * @throws BusinessException
	 * @author nibili 2017年4月7日
	 */
	public abstract Object failCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AlipayTradeRefundResponse response)
			throws BusinessException;

	/**
	 * 发生本地处理异常
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param response
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年5月16日
	 */
	public abstract Object errorCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Exception exception);

	/**
	 * 退款
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @author nibili 2017年4月7日
	 */
	@RequestMapping("/refund.json")
	public void refund(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
		try {
			//
			AlipayUnionConfig alipayConfig = getAlipayConfig(httpServletRequest);
			//
			AlipayTradeRefundModel model = getAlipayTradeRefundModel(httpServletRequest);
			// 实例化客户端
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayUnionConfig.URL, alipayConfig.getApp_id(), alipayConfig.getRsa_private_key(), AlipayUnionConfig.FORMAT,
					AlipayUnionConfig.CHARSET, alipayConfig.getAlipay_public_key(), alipayConfig.getSigntype());
			AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
			//
			request.setBizModel(model);
			AlipayTradeRefundResponse response = alipayClient.execute(request);
			if (response.isSuccess()) {
				System.out.println("调用成功");
				//
				successCallback(httpServletRequest, httpServletResponse, response);
			} else {
				System.out.println("调用失败");
				//
				failCallback(httpServletRequest, httpServletResponse, response);
			}
		} catch (AlipayApiException alipayApiException) {
			logger.error("支付宝异常", alipayApiException);
			errorCallback(httpServletRequest, httpServletResponse, alipayApiException);
		} catch (Exception ex) {
			logger.error("", ex);
			errorCallback(httpServletRequest, httpServletResponse, ex);
		}
	}
	//
	// /**
	// * app支付退款参数
	// *
	// * @author nibili 2017年4月7日
	// *
	// */
	// public static class AlipayAppRefundRequestParam {
	// /** String 特殊可选 64 订单支付时传入的商户订单号,不能和 trade_no同时为空。 20150320010101001 */
	// private String out_trade_no;
	// /** String 特殊可选 64 支付宝交易号，和商户订单号不能同时为空 2014112611001004680073956707 */
	// private String trade_no;
	// /** Price 必须 9 需要退款的金额，该金额不能大于订单金额,单位为元，支持两位小数 200.12 */
	// private String refund_amount;
	// /** String 可选 256 退款的原因说明 正常退款 */
	// private String refund_reason;
	// /** String 可选 64 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。 HZ01RF001 */
	// private String out_request_no;
	// /** String 可选 30 商户的操作员编号 OP001 */
	// private String operator_id;
	// /** String 可选 32 商户的门店编号 NJ_S_001 */
	// private String store_id;
	// /** String 可选 32 商户的终端编号 NJ_T_001 */
	// private String terminal_id;
	//
	// /**
	// * get String特殊可选64订单支付时传入的商户订单号不能和trade_no同时为空。20150320010101001
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getOut_trade_no() {
	// return out_trade_no;
	// }
	//
	// /**
	// * set String特殊可选64订单支付时传入的商户订单号不能和trade_no同时为空。20150320010101001
	// *
	// * @param out_trade_no
	// * @author nibili 2017年4月7日
	// */
	// public void setOut_trade_no(String out_trade_no) {
	// this.out_trade_no = out_trade_no;
	// }
	//
	// /**
	// * get String特殊可选64支付宝交易号，和商户订单号不能同时为空2014112611001004680073956707
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getTrade_no() {
	// return trade_no;
	// }
	//
	// /**
	// * set String特殊可选64支付宝交易号，和商户订单号不能同时为空2014112611001004680073956707
	// *
	// * @param trade_no
	// * @author nibili 2017年4月7日
	// */
	// public void setTrade_no(String trade_no) {
	// this.trade_no = trade_no;
	// }
	//
	// /**
	// * get Price必须9需要退款的金额，该金额不能大于订单金额单位为元，支持两位小数200.12
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getRefund_amount() {
	// return refund_amount;
	// }
	//
	// /**
	// * set Price必须9需要退款的金额，该金额不能大于订单金额单位为元，支持两位小数200.12
	// *
	// * @param refund_amount
	// * @author nibili 2017年4月7日
	// */
	// public void setRefund_amount(String refund_amount) {
	// this.refund_amount = refund_amount;
	// }
	//
	// /**
	// * get String可选256退款的原因说明正常退款
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getRefund_reason() {
	// return refund_reason;
	// }
	//
	// /**
	// * set String可选256退款的原因说明正常退款
	// *
	// * @param refund_reason
	// * @author nibili 2017年4月7日
	// */
	// public void setRefund_reason(String refund_reason) {
	// this.refund_reason = refund_reason;
	// }
	//
	// /**
	// * get String可选64标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。HZ01RF001
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getOut_request_no() {
	// return out_request_no;
	// }
	//
	// /**
	// * set String可选64标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。HZ01RF001
	// *
	// * @param out_request_no
	// * @author nibili 2017年4月7日
	// */
	// public void setOut_request_no(String out_request_no) {
	// this.out_request_no = out_request_no;
	// }
	//
	// /**
	// * get String可选30商户的操作员编号OP001
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getOperator_id() {
	// return operator_id;
	// }
	//
	// /**
	// * set String可选30商户的操作员编号OP001
	// *
	// * @param operator_id
	// * @author nibili 2017年4月7日
	// */
	// public void setOperator_id(String operator_id) {
	// this.operator_id = operator_id;
	// }
	//
	// /**
	// * get String可选32商户的门店编号NJ_S_001
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getStore_id() {
	// return store_id;
	// }
	//
	// /**
	// * set String可选32商户的门店编号NJ_S_001
	// *
	// * @param store_id
	// * @author nibili 2017年4月7日
	// */
	// public void setStore_id(String store_id) {
	// this.store_id = store_id;
	// }
	//
	// /**
	// * get String可选32商户的终端编号NJ_T_001
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getTerminal_id() {
	// return terminal_id;
	// }
	//
	// /**
	// * set String可选32商户的终端编号NJ_T_001
	// *
	// * @param terminal_id
	// * @author nibili 2017年4月7日
	// */
	// public void setTerminal_id(String terminal_id) {
	// this.terminal_id = terminal_id;
	// }
	//
	// }
}
